#include "stdafx.h"
#include "HMsgManager.h"
#include "HMessageMaker.h"
#include <memory>
#include "QTcpSocket"
#include "HActionDefines.h"


HMsgManager::HMsgManager()
{
}

HMsgManager::~HMsgManager()
{
}

HMsgManager& HMsgManager::GetInstance()
{
    static HMsgManager instance;
    return instance;
}

void HMsgManager::QueryUserName(QTcpSocket* pSock, QString const& userName)
{
    HMessageMaker dataMaker;

    std::shared_ptr<LoginAction> pLoginAction = std::make_shared<LoginAction>();
    pLoginAction->SetUserName(userName);
    pLoginAction->SetType(ActionType::kDataQueryName);
    pLoginAction->SetSuccess(false);

    QString msg = dataMaker.MakeQueryUserMessage(pLoginAction);

    HMsgManager::WriteSocketData(pSock, msg);
}

void HMsgManager::OnProcessAction(QTcpSocket* pSock, QString const& actionString)
{
}

void HMsgManager::ProcessAction(QTcpSocket* pSock, QString const& actionString)
{
    QJsonParseError jsonError;
    QJsonDocument doc = QJsonDocument::fromJson(actionString.toUtf8(), &jsonError);
    if (jsonError.error != QJsonParseError::NoError && !doc.isNull())
    {
        return;
    }

    ActionType actionType = ActionType::kDataNone;
    QJsonObject rootObj = doc.object();
    if (rootObj.contains("action"))
    {
        actionType = (ActionType)rootObj["action"].toInt();
    }

    if (actionType == ActionType::kDataQueryName)
    {
        std::shared_ptr<LoginAction> pAction = std::make_shared<LoginAction>();
        pAction->InFieldAction(rootObj);

        auto pLoginAction = std::static_pointer_cast<LoginAction>(pAction);
        pAction->SetSock(pSock);

        ProcessQueryUserName(std::move(pLoginAction));
    }
    else if (actionType == ActionType::kDataLogin)
    {
        std::shared_ptr<LoginAction> pAction = std::make_shared<LoginAction>();
        pAction->InFieldAction(rootObj);

        auto pLoginAction = std::static_pointer_cast<LoginAction>(pAction);

        pLoginAction->SetSock(pSock);

        ProcessLoginAction(std::move(pLoginAction));
    }
    else if (actionType == ActionType::kDataQueryNameResult)
    {
        std::shared_ptr<LoginAction> pAction = std::make_shared<LoginAction>();
        pAction->InFieldAction(rootObj);

        auto pLoginAction = std::static_pointer_cast<LoginAction>(pAction);

        pLoginAction->SetSock(pSock);

        ProcessQueryUserNameResult(std::move(pLoginAction));
    }
    else if (actionType == ActionType::kDataLoginResult)
    {
        std::shared_ptr<LoginAction> pAction = std::make_shared<LoginAction>();
        pAction->InFieldAction(rootObj);

        auto pLoginAction = std::static_pointer_cast<LoginAction>(pAction);

        pLoginAction->SetSock(pSock);

        ProcessLoginResult(std::move(pLoginAction));
    }
    else if (actionType == ActionType::kDataGetUserListResult)
    {
        std::shared_ptr<GetUserListAction> pAction = std::make_shared<GetUserListAction>();
        pAction->InFieldAction(rootObj);

        auto pLoginAction = std::static_pointer_cast<GetUserListAction>(pAction);

        pLoginAction->SetSock(pSock);

        ProcessGetUserInfoListResult(std::move(pLoginAction));
    }
    else if (actionType == ActionType::kGetDataMsg)
    {
        std::shared_ptr<UserMessageAction> pAction = std::make_shared<UserMessageAction>();
        pAction->InFieldAction(rootObj);

        auto pLoginAction = std::static_pointer_cast<UserMessageAction>(pAction);

        pLoginAction->SetSock(pSock);

        ProcessGetUserMessage(std::move(pLoginAction));
    }
    else
    {
        OnProcessAction(pSock, actionString);
    }
}

// server
void HMsgManager::OnGetSockReadReady()
{
    QTcpSocket* pTcpSock = (QTcpSocket*)sender();
    if (pTcpSock == nullptr)
    {
        return;
    }

    QByteArray strAction = pTcpSock->readAll();

    int nCount = *(int*)&strAction.data()[0];

    QString str = &strAction.data()[4];

    str.resize(nCount);

    ProcessAction(pTcpSock, str);
}

// server
void HMsgManager::ProcessLoginAction(std::shared_ptr<LoginAction> pAction)
{
    if (pAction == nullptr)
    {
        return;
    }

    QString userName = pAction->GetUserName();
    QTcpSocket* pSock = pAction->GetSock();

    emit sigLogin(pSock, userName);
}

// server
void HMsgManager::ProcessQueryUserName(std::shared_ptr<LoginAction> pAction)
{
    if (pAction == nullptr)
    {
        return;
    }

    QString userName = pAction->GetUserName();
    QTcpSocket* pSock = pAction->GetSock();

    emit sigQueryUserName(pSock, userName);
}

// client
void HMsgManager::ProcessQueryUserNameResult(std::shared_ptr<LoginAction> pAction)
{
    if (pAction == nullptr)
    {
        return;
    }

    bool isOk = pAction->IsSuccess();
    QString errMsg = pAction->GetErrMsg();

    emit sigQueryUserNameResult(isOk, errMsg);


    pAction->SetType(ActionType::kDataLogin);
    pAction->SetSuccess(false);

    HMessageMaker dataMaker;
    QString msg = dataMaker.MakeQueryUserMessage(pAction);

    QTcpSocket* pSock = pAction->GetSock();
    WriteSocketData(pSock, msg);
}

// client
void HMsgManager::ProcessLoginResult(std::shared_ptr<LoginAction> pAction)
{
    if (pAction == nullptr)
    {
        return;
    }

    bool isOk = pAction->IsSuccess();
    QString errMsg = pAction->GetErrMsg();
    QString token = pAction->GetToken();
    QString userName = pAction->GetUserName();

    emit sigLoginResult(isOk, userName, token, errMsg);
}

// client
void HMsgManager::ProcessGetUserInfoListResult(std::shared_ptr<GetUserListAction> pAction)
{
    if (pAction == nullptr)
    {
        return;
    }

    QString userName = pAction->GetUserName();
    QTcpSocket* pSock = pAction->GetSock();
    QString token = pAction->GetToken();
    QVector<UserInfo> userInfoList = pAction->GetUserInfoList();

    emit sigGetUserInfoListResult(userName, token, userInfoList);
}

void HMsgManager::ProcessGetUserMessage(std::shared_ptr<UserMessageAction> pAction)
{
    if (pAction == nullptr)
    {
        return;
    }

    QString userName = pAction->GetUserName();
    QString msg = pAction->GetPlanMessage();

    emit sigGetUserMessage(userName, msg);
}

void HMsgManager::RefreshUserList(QTcpSocket* pSock, QString const& userName, QString const& token)
{
    HMessageMaker dataMaker;
    QString msg = dataMaker.MakeGetUserInfoListMessage(userName, token);
    HMsgManager::WriteSocketData(pSock, msg);
}

void HMsgManager::WriteSocketData(QTcpSocket* pSocket, QString const& str)
{
    QByteArray buf;
    buf.resize(4);

    *((int*)&buf.data()[0]) = str.toUtf8().size();
    buf.append(str);

    pSocket->write(buf, buf.length());
}

void HMsgManager::DoSendMessage(QTcpSocket* m_pTcpSock, QString const& strUserName, QString const& clientToken, QString const& userMsg)
{
    HMessageMaker dataMaker;
    QString msg = dataMaker.MakeSendMessage(strUserName, clientToken, userMsg);
    HMsgManager::WriteSocketData(m_pTcpSock, msg);
}
